
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
                <style>
                    ul,li{
                        list-style-type: none;
                        margin:0;
                        padding:0
                    }
                li{
                    display: block;
                    padding:10px 20px;
                    background:#aaa;
                    color:#fff;
                    border-radius: 5px;
                    margin-top:20px;
                    text-align: center;
                }
                
                    </style>
                <title>js call native api</title>
            
                
    </head>
    <body>
        <ul>
            
            <li id="J_GotoBaidu">跳转至百度</li>
            <li id="J_NativeToJs">NativeToJs获取uid</li>
            <li id="J_HideTitle">hideTitle</li>
            <li id="J_ShowTitle">showTitle</li>
            <li id="J_PopPage">popPage1</li>
            <li id="J_OpenNewPage">openNewPage</li>
            <li id="J_PopPage2">popPage2</li>
            <li id="J_Resume">resume监听</li>
            <li id="J_Pause">pause监听</li>
            <li id="J_UA">自定义UA</li>
            <li id="J_BridgeScheme">自定义协议拦截</li>
            
            
        </ul>
        <div id="temp"></div>
        <div id="temp2"></div>
        
        <script>
        
        var ua = navigator.userAgent;
        var IOS = 'ios';
        var ANDROID = 'android';
        
        /**
         * 监听浏览器回退事件
         * @param actionToDo
         */
        var pageBackFromNextPage = function(actionToDo){
            
            // pageshow
            // UA.android && window.addEventListener('focus', actionToDo, false);
            window.addEventListener('pageshow', function (e) {
                if (e.persisted) {
                    actionToDo(e);
                }
            }, false);
                                    
            // visibilityChange
            document.addEventListener('visibilitychange', function (e) {
              if (document.visibilityState == 'visible' || !document.hidden) {
                  actionToDo(e);
              }
            }, false);
              
          // webkitVisibilityChange
          document.addEventListener('webkitVisibilitychange', function (e) {
            if (document.webkitVisibilityState == 'visible' || !document.webkitHidden) {
                actionToDo(e);
            }
          }, false);
        };
        
        /**
         * 监听浏览器暂停事件（压入后台）
         * @param actionToDo
         */
        var pagePause = function(actionToDo){
            
            // pageshow
            // UA.android && window.addEventListener('focus', actionToDo, false);
            window.addEventListener('pagehide', function (e) {
                if (e.persisted) {
                    actionToDo(e);
                }
            }, false);
            
            // visibilityChange
            document.addEventListener('visibilitychange', function (e) {
                  if (document.visibilityState == 'hidden' || document.hidden) {
                      actionToDo(e);
                  }
              }, false);
                                      
          // webkitVisibilityChange
          document.addEventListener('webkitVisibilitychange', function (e) {
                if (document.webkitVisibilityState == 'hidden' || document.webkitHidden) {
                    actionToDo(e);
                }
          }, false);
        };
        
        function getDeviceInfo(){ //获取设备信息
            var device = {
                type: null,
                version: null
            };
            //设备类型
            if (/\(i[^;]+;( U;)? CPU.+Mac OS X/.test(ua)) {
                // iOS: Mozilla/5.0 (iPhone; CPU iPhone OS 8_4_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12H321 AliApp(LX/5.8.1) AliTrip/5.8.1
                device.type = IOS;
                
                // iOS 版本号提取
                var iosVersion = /\b[0-9]+_[0-9]+(?:_[0-9]+)?\b/.exec(ua);
                if (iosVersion && iosVersion[0]) {
                    device.version = iosVersion[0].replace(/_/g, '.');
                }
            } else if (/Android/i.test(ua)) {
                device.type = ANDROID;
                var match = ua.match(/Android\s+([\d\.]+)/i);
                device.version = match && match[1];
            } else {
                device.type = undefined;
            }
                return device;
        }
                
        var JSBridge = {
            device: getDeviceInfo(),
            eventMap: {
              //事件队列
            },
            uid: 0,
            deviceRouter: function(method, params, callback, isHold){
                if(this.device.type == IOS){
                    this.iosMethod(method, params, callback, isHold);
                } else if (this.device.type == ANDROID){
                    this.androidMethod(method, params, callback, isHold);
                } else {
                    console.error("请在native端使用此方法：" + method);
                }
            },
            iosMethod: function(method, params, callback, isHold){ //ios通用方法
                var self = this;
                var uid = this.uid;
                
                if(callback){
                    this.eventMap[method + uid] = function(data){
                        callback && callback(data);
                        if(!isHold){
                            delete self.eventMap[method + uid];
                        }
                    };
                    this.uid = uid + 1;
                }
                
                try{
                    var msgObj = {
                        nativeMethod: method
                    };
                    if(callback){
                        msgObj.callback = method + uid;
                    }
                    if(params){
                        msgObj.params = JSON.stringify(params);
                    }
                
                    window.webkit.messageHandlers.JSBridge.postMessage(msgObj);
                }catch(e){
                    console.error(JSON.stringify(e));
                    console.error("需要在ios设备内使用WKWebView");
                }
                
            },
            androidMethod: function(method, params, callback, isHold){ //android通用方法
                
                var self = this;
                var uid = this.uid;
                
                if(callback){
                    this.eventMap[method + uid] = function(data){
                        callback && callback(data);
                        if(!isHold){
                            delete self.eventMap[method + uid];
                        }
                    };
                    this.uid = uid + 1;
                }
                
                try{
                
                    if(params && callback){
                        JSBridgeAndroid[method](JSON.stringify(params), method + uid);
                    } else if(params) {
                        JSBridgeAndroid[method](JSON.stringify(params));
                    } else if(callback) {
                        JSBridgeAndroid[method](method + uid);
                    } else {
                        JSBridgeAndroid[method]();
                    }
                
                }catch(e){
                    console.error(JSON.stringify(e));
                    console.error("需要在android设备内使用JSBridge功能，无全局对象JSBridgeAndroid");
                }
                
            },
            getDeviceId: function(callback){ //获取设备id
            
                this.deviceRouter("getDeviceId", null, callback);
                
            },
                
            openPage: function(url){ //打开新的webview
                
                this.deviceRouter("openPage", {url: url}, null);
                if(!this.device.type){
                    location.href = url;
                }
                
            },
                
            popPage: function(n){ //关闭页面
                
                if(!n) { n = 1 }
                this.deviceRouter("popPage", {step: n}, null);
                
                if(!this.device.type){
                    if(n == 1){
                        history.back();
                    } else {
                        history.go(-n);
                    }
                }
                // JSBridgeAndroid.popPage(n);
            },
                
            hideTitle: function(){ //隐藏native title bar
                
                this.deviceRouter("hideTitle", null, null);
                
                // JSBridgeAndroid.hideTitle();
            },
                
            showTitle: function(){ //显示native title bar
                
                this.deviceRouter("showTitle", null, null);
                
                // JSBridgeAndroid.showTitle();
            },
                
            addResumeEvent: function(callback){ //resume
                
                this.deviceRouter("addResumeEvent", null, callback);
                
                if(!this.device.type){
                    pageBackFromNextPage(callback);
                }
                
                // JSBridgeAndroid.addResumeEvent(name + uid);
                
            },
                
            addPauseEvent: function(callback){ //pause
                
                this.deviceRouter("addPauseEvent", null, callback);
                
                if(!this.device.type){
                    pagePause(callback);
                }
            }
                
        };
        
        var J_GotoBaidu = document.getElementById("J_GotoBaidu");
        J_GotoBaidu.onclick = function(){
            
            JSBridge.openPage("https://www.baidu.com");
            
        };
        
        var J_NativeToJs = document.getElementById("J_NativeToJs");
        J_NativeToJs.onclick = function(){
            
            JSBridge.getDeviceId(function(data){
                                 
                                 document.getElementById('temp').innerHTML = data;
                                 
                                 });
                                 
        };
        
        var J_HideTitle = document.getElementById("J_HideTitle");
        J_HideTitle.onclick = function(){
            JSBridge.hideTitle();
        };
        var J_ShowTitle = document.getElementById("J_ShowTitle");
        J_ShowTitle.onclick = function(){
            JSBridge.showTitle();
        };
        var J_PopPage = document.getElementById("J_PopPage");
        J_PopPage.onclick = function(){
            JSBridge.popPage();
        };
        var J_OpenNewPage = document.getElementById("J_OpenNewPage");
        J_OpenNewPage.onclick = function(){
            JSBridge.openPage();
        };
        var J_PopPage2 = document.getElementById("J_PopPage2");
        J_PopPage2.onclick = function(){
            JSBridge.popPage(2);
        };
        
        
        var J_Resume = document.getElementById("J_Resume");
        J_Resume.onclick = function(){
            
            JSBridge.addResumeEvent(function(){
                                 
                                 document.getElementById('temp').innerHTML = "app 被压入前台";
                                 
                                 });
                                 
        };
        
        var J_Pause = document.getElementById("J_Pause");
        J_Pause.onclick = function(){
            
            JSBridge.addPauseEvent(function(){
                            
                            document.getElementById('temp2').innerHTML = "app 被压入后台";
                            
                            });
                            
        };
        
        var J_UA = document.getElementById("J_UA");
        J_UA.onclick = function(){
            
            alert(navigator.userAgent);
                           
        };
        
        var J_BridgeScheme = document.getElementById("J_BridgeScheme");
        J_BridgeScheme.onclick = function(){
            
            //ios接收到的scheme的值 始终为小写
            var body = document.getElementsByTagName("body")[0];
            var iframe = document.createElement('iframe');
            iframe.src = "jsbridge://openPage?url=" + encodeURIComponent("https://www.baidu.com");
            body.appendChild(iframe);
            //location.href = "jsbridge://openPage?url=" + encodeURIComponent("https://www.baidu.com");
            
        };
        
        
        
            </script>
    </body>
</html>
